import { _decorator, Component, instantiate, Node, Prefab, EventTarget, tween, UIOpacity } from 'cc'
import { Logger, ServiceLocator } from '../utils'
import { FrameEvents, RoleType, ServiceName } from '../../enum'
import { MinorPrefab, MajorPrefab, NarratorPrefab } from '../components'
import type { Chapter } from '../store'
const { ccclass, property } = _decorator

@ccclass('TextFrame')
export class TextFrame extends Component {
    #logger = new Logger('对话帧')
    #services = ServiceLocator

    @property(Prefab)
    minorPrefab: Prefab

    @property(Prefab)
    majorPrefab: Prefab

    @property(Prefab)
    narratorPrefab: Prefab

    activeDialog: Node = null

    get chapter(): Chapter {
        return this.#services.get(ServiceName.Chapter)
    }

    get events(): EventTarget {
        return this.#services.get(ServiceName.Event)
    }

    run(content: LDContent.DialogContent) {
        this.#logger.debug('处理对话帧 %o', content)
        switch (content.dialog.who.type) {
            case RoleType.MINOR:
                this.initMinor(content)
                break
            case RoleType.MAJOR:
                this.initMajor(content)
                break
            case RoleType.NARRATOR:
                this.initNarrator(content)
                break
        }
    }

    clear() {
        return new Promise((resolve) => {
            if (this.activeDialog) {
                tween(this.activeDialog.getComponent(UIOpacity))
                    .to(0.5, { opacity: 0 })
                    .call(() => {
                        this.activeDialog.removeFromParent()
                        resolve(true)
                    })
                    .start()
            } else {
                return resolve(true)
            }
        })
    }

    async initMinor(content: LDContent.DialogContent) {
        if (this.activeDialog?.name == 'minor') {

        } else if (this.activeDialog) {
            await this.clear()
            this.activeDialog = instantiate(this.minorPrefab)
            this.node.addChild(this.activeDialog)
        } else {
            this.activeDialog = instantiate(this.minorPrefab)
            this.node.addChild(this.activeDialog)
        }
        const MinorComponent = this.activeDialog.getComponent(MinorPrefab)
        const role = this.chapter.getRole(content.dialog.who.roleId)
        this.#logger.debug('初始化配角帧', MinorComponent)

        MinorComponent.nickName.string = role.nickname
        await MinorComponent.print(content.dialog.what.text)
        this.events.emit(FrameEvents.frameLock, false)
    }

    async initMajor(content: LDContent.DialogContent) {
        if (this.activeDialog?.name == 'major') {

        } else if (this.activeDialog) {
            await this.clear()
            this.activeDialog = instantiate(this.majorPrefab)
            this.node.addChild(this.activeDialog)
        } else {
            this.activeDialog = instantiate(this.majorPrefab)
            this.node.addChild(this.activeDialog)
        }
        const MajorComponent = this.activeDialog.getComponent(MajorPrefab)
        this.#logger.debug('初始化主角帧', MajorComponent)

        MajorComponent.nickName.string = '我'
        const bool = await MajorComponent.print(content.dialog.what.text)

        this.#logger.debug('对话结束', bool)
        this.events.emit(FrameEvents.frameLock, false)

    }

    async initNarrator(content: LDContent.DialogContent) {
        if (this.activeDialog?.name == RoleType.NARRATOR) {

        } else if (this.activeDialog) {
            await this.clear()
            this.activeDialog = instantiate(this.narratorPrefab)
            this.node.addChild(this.activeDialog)
        } else {
            this.activeDialog = instantiate(this.narratorPrefab)
            this.node.addChild(this.activeDialog)
        }
        this.#logger.debug('初始化旁白帧', content)
        const NarratorComponent = this.activeDialog.getComponent(NarratorPrefab)

        const bool = await NarratorComponent.print(content.dialog.what.text)
        this.#logger.debug('旁白对话结束', bool)
        this.events.emit(FrameEvents.frameLock, false)
    }
}


